
/*
 *  
 *
 *  Copyright (C) Microsoft Corporation.  All rights reserved
 *
 *  
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Xml;
using Microsoft.Crm.DataBindining;

namespace CRMScenarios
{
	public partial class LookUpDialogBox : Form
	{

        BaseUserControl parent = null;
        BusinessEntityCollection currentRelatedBec = null;
        string[] savedQueryDetails = null;
        string[][] MainComboMapping = null;
        PageInfo pageInfo = null;
        bool viewComboSearch = false;

        private int index(ref string[] arr, string el)
        {
            if (arr == null)
            {
                return -1;
            }
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] == el)
                {
                    return i;
                }
            }
            return -1;
        }

        private string MainEntityName()
        {
            int iIndex = index(ref MainComboMapping[0], (string)this.comboBoxEntityTypeLookFor.SelectedItem);
            return ((iIndex != -1) ? (MainComboMapping[1][iIndex]) : (string.Empty));
        }

		public LookUpDialogBox()
		{
			InitializeComponent();
            InitialezeControls();
            tBoxSearchFor.KeyDown += new KeyEventHandler(tBoxSearchFor_KeyDown);
            this.ResizeRedraw = true;
            this.firstPagePic.Image = global::CRMScenarios.Resources.frew;
            this.previousPagePic.Image = global::CRMScenarios.Resources.rew;
            this.nextPagePic.Image = global::CRMScenarios.Resources.fwd;
            pageInfo = new PageInfo();
		}

        private void tBoxSearchFor_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                btnSearch_Click(null, null);
            }
        }

        private void InitialezeControls()
        {
            foreach (Control ctrl in this.Controls)
            {
                if ((ctrl is Label) || (ctrl is LinkLabel))
                {
                    continue;
                }

                ctrl.Enabled = false;
            }

            lblDescription.Enabled = true;

            DisablePaging();

            MainComboMapping = CrmConnector.getEntityListFromCRM(PrivilegeType.Read);
            if ((MainComboMapping == null) || (MainComboMapping.Length == 0))
            {
                return;
            }
            string[] entityList = MainComboMapping[0];
            if ((entityList == null) || (entityList.Length == 0))
            {
                return;
            }

            populateCombo(this.comboBoxEntityTypeLookFor, entityList);
            this.comboBoxEntityTypeLookFor.Enabled = true;

            this.tBoxSearchFor.MaxLength = 100;
            this.tBoxSearchFor.AutoCompleteMode = AutoCompleteMode.Suggest;
            this.tBoxSearchFor.AutoCompleteSource = AutoCompleteSource.CustomSource;
            this.btnSearch.Enabled = true;

            this.listViewRecords.CellDoubleClick += new DataGridViewCellEventHandler(listViewRecords_DoubleClick);
            this.listViewRecords.SelectionChanged += new EventHandler(listViewRecords_SelectedIndexChanged);
        }

        private void OpenPage(string Url)
        {
            if ((Url == null) || (Url == string.Empty))
            {
                return;
            }
            try
            {
                System.Diagnostics.Process.Start("iexplore", Url);
            }
            catch (Exception)
            { }
        }

        private void listViewRecords_DoubleClick(object sender, EventArgs e)
        {
            if (((DataGridViewCellEventArgs)e).RowIndex < 0)
            {
                return;
            }
            btnOk_Click(null, null);
        }

        public void InitializeLookUpDialogBox(string entityType, string search, BaseUserControl parentForm)
        {         
            // paging is not done.
            this.comboBoxEntityTypeLookFor.SelectedItem = CrmConnector.NameToDisplay(entityType);
            this.comboBoxEntityTypeLookFor.Enabled = true;
            this.tBoxSearchFor.Text = search;
            this.tBoxSearchFor.Enabled = true;
            parent = parentForm;
            PageChange(pageInfo.FirstPage());   
        }

        private void FillRelatedRecordsView(string entityType, string[] columnNames)
        {
            this.btnCancel.Enabled = true;
            this.btnOk.Enabled = false;
            this.listViewRecords.Columns.Clear();
            dgvSummary.Rows.Clear();

            if (currentRelatedBec == null)
            {
                this.listViewRecords.Enabled = false;
                this.lblRecordsFound.Text = global::CRMScenarios.Resources.NoResultFound;
                this.lblNoRecords.Text = global::CRMScenarios.Resources.NoResultFound;
                this.lblNoRecords.Visible = true;
                return;
            }

            listViewRecords.AutoGenerateColumns = true;
            listViewRecords.DataError += new DataGridViewDataErrorEventHandler(listViewRecords_DataError);
            IDictionary nameToTypeMap = CrmConnector.GetNameToTypeMapping(entityType, columnNames);
            listViewRecords.DataSource = UniversalEntity.CreateFromDynamicEntityCollection(currentRelatedBec, ref nameToTypeMap);
            string [] DataBndColumnNames = CrmConnector.GetDataBoundAttribNames(entityType, columnNames);
            StringCollection columNameCollection = CrmConnector.ArrayToCollection(DataBndColumnNames);
            columNameCollection.Remove(CrmConnector.GetEntityMetaData(entityType).PrimaryKey);

            foreach (DataGridViewColumn s in this.listViewRecords.Columns)
            {
                if (s != null)
                {
                    s.Visible = false;
                }
            }

            int TotalColumnWidth = 0;
            foreach (string lookUpCol in columNameCollection)
            {
                string dispName = CrmConnector.GetDisplayNameOfAttribute(entityType, lookUpCol);
                string displayName = ((dispName == null) || (dispName == string.Empty)) ? (lookUpCol) : (dispName);
                if (listViewRecords.Columns.Contains(lookUpCol))
                {
                    listViewRecords.Columns[lookUpCol].HeaderText = displayName;
                }
                else 
                {
                    listViewRecords.Columns.Add(lookUpCol, displayName);
                }
                listViewRecords.Columns[lookUpCol].DisplayIndex = columNameCollection.IndexOf(lookUpCol);
                listViewRecords.Columns[lookUpCol].Visible = true;
                listViewRecords.Columns[lookUpCol].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                TotalColumnWidth += listViewRecords.Columns[lookUpCol].Width;
            }

            if (TotalColumnWidth < listViewRecords.Width)
            {
                foreach (string lookUpCol in columNameCollection)
                {
                    listViewRecords.Columns[lookUpCol].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                }
            }

            this.listViewRecords.Enabled = true;

            //bool singleRecord = (currentRelatedBec.BusinessEntities.Length == 1);
            //string pluralOrNot = ((singleRecord) ? (global::CRMScenarios.Resources.OneRecordFound) : (global::CRMScenarios.Resources.MultipleRecordsFound));
            //this.lblRecordsFound.Text = currentRelatedBec.BusinessEntities.Length.ToString() + pluralOrNot;
            //this.lblRecordsFound.Visible = true;

            if (currentRelatedBec.BusinessEntities.Length == 0)
            {
                lblNoRecords.Text = global::CRMScenarios.Resources.NoResultFound;
                lblRecordsFound.Text = global::CRMScenarios.Resources.NoResultFound;
                lblNoRecords.Visible = true;
                lblRecordsFound.Visible = true;
            }

            AddContextMenu();
            EnablePaging();
        }

        private void listViewRecords_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            // TODO
            // DONT MASK THE ERROR
            // TODO 
            //listViewRecords.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = string.Empty;
            e.ThrowException = false;
        }

        private void populateCombo(ComboBox cmBox, StringCollection strings)
        {
            if ((cmBox == null) || (strings == null))
            {
                return;
            }

            foreach (string s in strings)
            {
                cmBox.Items.Add((object)s);
            }
        }

        private void populateCombo(ComboBox cmBox, string[] strings)
        {
            if ((cmBox == null) || (strings == null))
            {
                return;
            }

            foreach (string s in strings)
            {
                cmBox.Items.Add((object)s);
            }
        }

        private void LookUpDialogBox_Load(object sender, EventArgs e)
        { 
        }
           
        private void comboBoxEntityTypeLookFor_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.listViewRecords.Columns.Clear();
            DisablePaging();
            this.tBoxSearchFor.Text = string.Empty;
            this.btnOk.Enabled = false;
            this.listViewRecords.Enabled = false;
            this.lblRecordsFound.Visible = false;
            this.lblNoRecords.Visible = false;
            this.cmBoxView.Enabled = true;
            savedQueryDetails = CrmConnector.GetViewsForLookupDlg(this.MainEntityName());
            if (savedQueryDetails == null)
            {
                Util.ShowError(global::CRMScenarios.Resources.ErrorInSearching);
                return;
            }
            RefreshSavedQueryCombo();
        }

        private void RefreshSavedQueryCombo()
        {
            this.cmBoxView.Items.Clear();
            if (savedQueryDetails == null)
            {
                return;
            }
            string[] savedQueryNames = new string[savedQueryDetails.Length / 2];
            for (int i = 0; i < savedQueryNames.Length; i++)
            {
                savedQueryNames[i] = savedQueryDetails[2 * i];
            }
            populateCombo(this.cmBoxView, savedQueryNames); // to be managed to get the list of views!!
            this.cmBoxView.SelectedItem = string.Empty;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if ((currentRelatedBec != null) && (currentRelatedBec.BusinessEntities.Length >= this.listViewRecords.SelectedRows[0].Index))
            {
                parent.getDetailsOfTheEntityAndDisplay(currentRelatedBec.BusinessEntities[this.listViewRecords.SelectedRows[0].Index], this.MainEntityName());
            }
            this.Dispose();
        }

        private void UpdateSummary(ref BusinessEntity be, string[][] pView)
        {
            dgvSummary.Rows.Clear();
            BusinessEntity beWithDetails = CrmConnector.GetSpecifiedDetailsOfThisEnity(be, MainEntityName(), pView[1]);

            pView[1] = CrmConnector.GetDataBoundAttribNames(MainEntityName(), pView[1]);
            if ( (beWithDetails == null) || (pView == null) || (pView[1] == null))
            {
                return;
            }
            for (int i = 0; i < pView[0].Length; i++)
            {
                string value = null;
                value = (string)CrmConnector.GetAttribute(ref beWithDetails, pView[1][i]);
                string[] row = { pView[0][i], ((value == null) ? (string.Empty) : (value)) };
                dgvSummary.Rows.Add(row);
            }
            dgvSummary.Columns[0].Visible = true;
            dgvSummary.Columns[1].Visible = true;
        }

        private void listViewRecords_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listViewRecords.SelectedRows.Count != 0)
            {
                this.btnOk.Enabled = true;
                this.lblNoRecords.Visible = false;

                int totalRecords = currentRelatedBec.BusinessEntities.Length;
                this.lblRecordsFound.Text = string.Format(System.Globalization.CultureInfo.CurrentUICulture, global::CRMScenarios.Resources.oneOfNSelected, totalRecords);

                string[][] previewDetails = CrmConnector.getPreviewDetails(MainEntityName());
                if ( (previewDetails == null) || (previewDetails.Length == 0) || (previewDetails[0].Length == 0))
                {
                    return;
                }
                dgvSummary.Enabled = true;
                UpdateSummary(ref currentRelatedBec.BusinessEntities[this.listViewRecords.SelectedRows[0].Index], previewDetails);
            }
            else
            {
                this.btnOk.Enabled = false;
                dgvSummary.Rows.Clear();
                dgvSummary.Enabled = false;
                this.lblNoRecords.Text = global::CRMScenarios.Resources.NoRecordSelected;
                this.lblNoRecords.Visible = true;
                this.lblRecordsFound.Text = global::CRMScenarios.Resources.NoRecordSelected;
            }
            this.lblRecordsFound.Visible = true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            parent.getDetailsOfTheEntityAndDisplay(null, string.Empty);
            this.Dispose();
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (tBoxSearchFor.Text.Trim() == string.Empty)
            {
                Util.ShowMsg(global::CRMScenarios.Resources.NoSearchCriteria);
                return;
            }
            //  972 
            viewComboSearch = false;
            DisablePaging();
            RefreshSavedQueryCombo();
            this.btnSearch.Enabled = false;
            this.Cursor = Cursors.WaitCursor;

            PageChange(pageInfo.FirstPage());

            //  972 
            this.btnSearch.Enabled = true;
            this.Cursor = Cursors.Default;
        }

        private void tBoxSearchFor_TextChanged(object sender, EventArgs e)
        {
        }

        private void AddContextMenu()
        {

            foreach (DataGridViewRow row in this.listViewRecords.Rows)
            {
                foreach (DataGridViewCell cell in row.Cells)
                {
                    cell.ErrorText = string.Empty;
                    //cell.ToolTipText = global::CRMScenarios.Resources.ToolTipRelatedRecordView;
                }
            }
        }

        private string[] SelectedSavedQuery()
        {
            string[] selectedSavedQuery = null;
            this.tBoxSearchFor.Text = string.Empty;
            if (savedQueryDetails == null)
            {
                return null;
            }
            for (int i = 0; i < savedQueryDetails.Length; i += 2) // Even - name & Odd - query
            {
                if (this.cmBoxView.Text == savedQueryDetails[i])
                {
                    selectedSavedQuery = new string[2];
                    selectedSavedQuery[0] = savedQueryDetails[i]; // name, at 0
                    selectedSavedQuery[1] = savedQueryDetails[i + 1]; // then at 1, query
                    break;
                }
            }
            return selectedSavedQuery;
        }

        private void cmBoxView_SelectedIndexChanged(object sender, EventArgs e)
        {
            viewComboSearch = true;
            DisablePaging();
            PageChange(pageInfo.FirstPage());
        }

        /// <summary>
        /// Change the page according to the information provided in the pInfo.
        /// </summary>
        /// <param name="pInfo"></param>
        private void PageChange(PagingInfo pInfo)
        {
            this.lblRecordsFound.Visible = false;
            this.lblNoRecords.Visible = false;

            string entityType = MainEntityName();
            string search = this.tBoxSearchFor.Text;
            string searchPattern = (((search == null) || (search == string.Empty)) ? ("*") : (search));
            string[] columnNames = null;
            if (!viewComboSearch)
            {
                currentRelatedBec = CrmConnector.SearchQkBringLookUp(entityType, searchPattern, pInfo);
                columnNames = CrmConnector.GetQkColumnsIfNoLookUpAvailable(entityType);
            }
            else
            {
                string [] selectedSavedQuery = SelectedSavedQuery();
                if (selectedSavedQuery == null)
                {
                    currentRelatedBec = null;
                    return;
                }
                currentRelatedBec = CrmConnector.GetEntitiesWithThisView("*", selectedSavedQuery[1], pInfo, selectedSavedQuery[0], entityType);
                columnNames = CrmConnector.ColumnsFromLayOutXmlForTheView(entityType, selectedSavedQuery[0]);
                if (columnNames == null)
                {
                    columnNames = CrmConnector.getLookupAttributes(selectedSavedQuery[1], "/fetch/entity/attribute", "name");
                }
            }

            if (currentRelatedBec == null)
            {
                Util.ShowError(global::CRMScenarios.Resources.ErrorInSearching);
                return;
            }

            if (columnNames == null)
            {
                return;
            }
            FillRelatedRecordsView(entityType, columnNames);
        }

        /// <summary>
        /// Action on click on first page button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void firstPagePic_Click(object sender, EventArgs e)
        {
            PageChange(pageInfo.FirstPage());
            //EnablePaging();
        }

        /// <summary>
        /// Action on click on previous page button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void previousPagePic_Click(object sender, EventArgs e)
        {
            PageChange(pageInfo.PrevPage());
            //EnablePaging();
        }

        /// <summary>
        /// Action on click on next page button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void nextPagePic_Click(object sender, EventArgs e)
        {
            PageChange(pageInfo.NextPage());
            //EnablePaging();
        }

        /// <summary>
        /// Have a look at the present situation (bec count, page number etc)
        /// and decide which all buttons need to be enabled/disabled.
        /// </summary>
        private void EnablePaging()
        {
            int currentPage = pageInfo.CurrentPage();
            if ((currentRelatedBec.BusinessEntities.Length == 0) && (currentPage == 0))
            {
                DisablePaging();
                return;
            }

            int currentCount = currentRelatedBec.BusinessEntities.Length;
            firstPagePic.Enabled = previousPagePic.Enabled = !(currentPage == 1);
            nextPagePic.Enabled = !(currentCount < pageInfo.MaxRecCountInGrid);

            firstPagePic.Visible = true;
            previousPagePic.Visible = true;
            nextPagePic.Visible = true;
            lblPageNum.Text = global::CRMScenarios.Resources.LabelPage + currentPage.ToString(System.Globalization.CultureInfo.InvariantCulture);
            lblPageNum.Visible = lblPageNum.Enabled = true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void DisablePaging()
        {
            firstPagePic.Enabled    = firstPagePic.Visible      = false;
            previousPagePic.Enabled = previousPagePic.Visible   = false;
            nextPagePic.Enabled     = nextPagePic.Visible       = false;
            lblPageNum.Enabled      = lblPageNum.Visible           = false;
        }

        private void dgvSummary_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }

        private void lblDescription_Click(object sender, EventArgs e)
        {

        }
    }
}